package api

import (
	"fmt"
	"vblog/app/blog"
	"vblog/app/token"
	"vblog/app/user"
	"vblog/common"
	"vblog/exception"
	"vblog/middleware"
	"vblog/response"

	"github.com/gin-gonic/gin"
)

// 注册路由
func (b *BlogApiHandler) Registry(r gin.IRouter) {
	// 创建路由组
	v := r.Group("v1").Group("blog")

	v.GET("/", b.QueryBlog)

	v.GET("/:id", b.DescribeBlog)

	// 对下面的handler使用认证中间件
	v.Use(middleware.NewMiddleware().Auth)

	v.POST("/", middleware.Required(user.ROLE_AUTHOR), b.CreateBlog)

	v.PUT("/:id", middleware.Required(user.ROLE_AUTHOR), b.Update_PutBlog)

	v.PATCH("/:id", middleware.Required(user.ROLE_AUTHOR), b.Update_PatchBlog)

	v.DELETE("/:id", middleware.Required(user.ROLE_AUTHOR), b.DeleteBlog)

	v.POST("/:id/audit", middleware.Required(user.ROLE_AUDITOR), b.AuditBlog)
}

func (b *BlogApiHandler) CreateBlog(c *gin.Context) {
	// 获取认证后的token来补充CreateBy属性
	tkobj := c.Keys[token.TOKEN_GIN_KEY_NAME]
	// 断言
	tk := tkobj.(*token.Token)

	// 1.接收请求
	req := blog.NewCreateBlogRequest()
	err := c.BindJSON(req)
	if err != nil {
		response.Fail(c, err)
	}

	// 补充CreateBy属性
	req.CreateBy = tk.UserName

	// 2.处理请求
	ins, err := b.bsvc.CreateBlog(c.Request.Context(), req)
	if err != nil {
		response.Fail(c, err)
		// 记得加return
		return
	}

	// 3.返回响应
	response.Success(c, ins)
}

func (b *BlogApiHandler) QueryBlog(c *gin.Context) {
	// 1.接收请求
	req := blog.NewQueryBlogRequest()
	// Gin 自动绑定查询参数到结构体
	err := c.ShouldBindQuery(req)
	if err != nil {
		response.Fail(c, err)
		return
	}

	switch c.Query("status") {
	case "draft":
		s := blog.STATUS_DRAFT
		req.Status = &s
	case "published":
		s1 := blog.STATUS_PUBLISHED
		req.Status = &s1
	}

	// 2.处理请求
	ins, err := b.bsvc.QueryBlog(c.Request.Context(), req)
	if err != nil {
		response.Fail(c, err)
		return
	}

	// 3.返回响应
	response.Success(c, ins)
}

func (b *BlogApiHandler) DescribeBlog(c *gin.Context) {
	// 1.接收请求
	req := blog.NewDescribeBlogRequest()
	req.BlogId = c.Param("id")

	// 2.处理请求
	ins, err := b.bsvc.DescribeBlog(c.Request.Context(), req)
	if err != nil {
		response.Fail(c, err)
		return
	}

	// 3.返回响应
	response.Success(c, ins)

}

func (b *BlogApiHandler) Update_PutBlog(c *gin.Context) {
	// 1.接收请求
	req := blog.NewUpdateBlogRequest_Put()
	req.BlogId = c.Param("id")
	err := c.BindJSON(req.CreateBlogRequest)
	if err != nil {
		response.Fail(c, err)
		return
	}

	// 补充获取Scope值的逻辑
	tkObj := c.Keys[token.TOKEN_GIN_KEY_NAME]
	if tkObj == nil {
		response.Fail(c, exception.NewPermissionDeny("token not found"))
		return
	}

	i, ok := tkObj.(*token.Token)
	if !ok {
		response.Fail(c, exception.NewPermissionDeny("token not an *token.Token"))
		return
	}

	req.Scope = &common.Scope{	// 注意这里的写法
		UserId: fmt.Sprintf("%d", i.UserId),
	}

	// 2.处理请求
	ins, err := b.bsvc.UpdateBlog(c.Request.Context(), req)
	if err != nil {
		response.Fail(c, err)
		return
	}

	// 3.返回响应
	response.Success(c, ins)

}

func (b *BlogApiHandler) Update_PatchBlog(c *gin.Context) {
	// 1.接收请求
	req := blog.UpdateBlogRequest_Patch()
	req.BlogId = c.Param("id")

	// 2.处理请求
	ins, err := b.bsvc.UpdateBlog(c.Request.Context(), req)
	if err != nil {
		response.Fail(c, err)
		return
	}

	// 3.返回响应
	response.Success(c, ins)
}

func (b *BlogApiHandler) DeleteBlog(c *gin.Context) {
	// 1.接收请求
	req := blog.NewDeleteBlogRequest()
	req.BlogId = c.Param("id")

	// 2.处理请求
	err := b.bsvc.DeleteBlog(c.Request.Context(), req)
	if err != nil {
		response.Fail(c, err)
		return
	}

	// 3.返回响应
	response.Success(c, "OK")
}

func (b *BlogApiHandler) AuditBlog(c *gin.Context) {
	req := blog.NewAuditBlogRequest()
	req.BlogId = c.Param("id")

	ins, err := b.bsvc.AuditBlog(c.Request.Context(), req)
	if err != nil {
		response.Fail(c, err)
		return
	}

	response.Success(c, ins)
}
